package com.yupi.yupicturebackend.manager.cos;

import cn.hutool.core.io.FileUtil;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.exception.CosClientException;
import com.qcloud.cos.exception.CosServiceException;
import com.qcloud.cos.model.*;
import com.qcloud.cos.transfer.TransferManager;
import com.qcloud.cos.transfer.TransferManagerConfiguration;
import com.qcloud.cos.transfer.Upload;
import com.yupi.yupicturebackend.config.CosClientConfig;
import org.springframework.stereotype.Component;
import com.qcloud.cos.model.ciModel.persistence.PicOperations;

import javax.annotation.Resource;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * 通用功能：文件上传、文件下载
 */
@Component
public class CosManager {
    @Resource
    CosClientConfig cosClientConfig;
    @Resource
    COSClient cosClient;
    @Resource
    TransferManager transferManager;

    /**
     * 文件上传（图片、视频、音频、文件都行）
     *
     * @param key
     * @param file
     * @return
     */
    // key:  指定文件上传到 COS 上的路径，即对象键。例如对象键为 folder/picture.jpg，则表示将文件 picture.jpg 上传到 folder 路径下
    // file: 指定要上传的文件
    // bucketName: 指定文件将要存放的存储桶
    public PutObjectResult putObject(String key, File file) {
        PutObjectRequest putObjectRequest = new PutObjectRequest(cosClientConfig.getBucket(), key, file);
        return cosClient.putObject(putObjectRequest);
    }

    /**
     * 文件下载
     *
     * @param key 唯一键
     */
    public COSObject getObject(String key) {
        GetObjectRequest getObjectRequest = new GetObjectRequest(cosClientConfig.getBucket(), key);
        return cosClient.getObject(getObjectRequest);
    }

    /**
     * 上传对象（附带图片信息）
     *
     * @param key  唯一键
     * @param file 文件
     */
    public PutObjectResult putPictureObject(String key, File file) {
        PutObjectRequest putObjectRequest = new PutObjectRequest(cosClientConfig.getBucket(), key,
                file);
        // 对图片进行处理（获取基本信息也被视作为一种处理）
        PicOperations picOperations = new PicOperations();
        // 1 表示返回原图信息
        picOperations.setIsPicInfo(1);

        //设置一些图片处理规则，这是规则集合
        List<PicOperations.Rule> rules = new ArrayList<>();

        // 图片压缩规则（转成 webp 格式）
        PicOperations.Rule compressRule = new PicOperations.Rule();
        String webpKey = FileUtil.mainName(key) + ".webp";
        compressRule.setRule("imageMogr2/format/webp");
        compressRule.setBucket(cosClientConfig.getBucket());
        compressRule.setFileId(webpKey);
        rules.add(compressRule);

        //图片缩略图规则
        //如果图片大小 > 20kb，就进行缩略，生成缩略图
        if(file.length() > 2 * 1024){
            PicOperations.Rule thumbnailRule = new PicOperations.Rule();
            //这里的jpg是自己加的，原本为FileUtil.mainName.getSuffix(),但是有些图片后缀是一些乱七八糟的字母，图片解析不出来
            //这里就强行全部转成.jpg
            String thumbnailKey = FileUtil.mainName(key) + "_thumbnail." + "jpg";
            thumbnailRule.setFileId(thumbnailKey);
            thumbnailRule.setBucket(cosClientConfig.getBucket());
            // 缩放规则 /thumbnail/<Width>x<Height>>（如果大于原图宽高，则不处理）
            thumbnailRule.setRule(String.format("imageMogr2/thumbnail/%sx%s>", 256, 256));
            rules.add(thumbnailRule);
        }

        // 构造处理参数
        picOperations.setRules(rules);
        putObjectRequest.setPicOperations(picOperations);
        return cosClient.putObject(putObjectRequest);
    }

    /**
     * 分块上传、断点续传(待做)
     *
     * @return
     * @throws CosServiceException
     * @throws CosClientException
     */
    public void upload(String key,File file){

        // 设置高级接口的配置项
        // 分块上传阈值和分块大小分别设置为 5MB 和 1MB（若不特殊设置，分块上传阈值和分块大小的默认值均为5MB）
        TransferManagerConfiguration transferManagerConfiguration = new TransferManagerConfiguration();
        transferManagerConfiguration.setMultipartUploadThreshold(5 * 1024 * 1024);
        transferManagerConfiguration.setMinimumUploadPartSize(1 * 1024 * 1024);
        transferManager.setConfiguration(transferManagerConfiguration);

        // 存储桶的命名格式为 BucketName-APPID，此处填写的存储桶名称必须为此格式:examplebucket-1250000000
        String bucketName = cosClientConfig.getBucket() + "-1250000000";

        PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, file);

        try {
            // 高级接口会返回一个异步结果Upload
            // 可同步地调用 waitForUploadResult 方法等待上传完成，成功返回 UploadResult, 失败抛出异常
            Upload upload = transferManager.upload(putObjectRequest);
            UploadResult uploadResult = upload.waitForUploadResult();
        } catch (CosServiceException e) {
            e.printStackTrace();
        } catch (CosClientException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 确定本进程不再使用 transferManager 实例之后，关闭即可
        // 详细代码参见本页：高级接口 -> 关闭 TransferManager
        transferManager.shutdownNow();
    }

    /**
     * 文件删除
     * @param key 文件key
     */
    public void deleteObject(String key) throws CosClientException{
        cosClient.deleteObject(cosClientConfig.getBucket(),key);
    }


}
